home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / app / image_new.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-25  |  9.3 KB  |  363 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
  3.  * 
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <string.h>
  22.  
  23. #include <gtk/gtk.h>
  24.  
  25. #include "image_new.h"
  26.  
  27. #include "appenv.h"
  28. #include "apptypes.h"
  29. #include "gimprc.h"
  30. #include "file_new_dialog.h"
  31. #include "tile_manager_pvt.h"
  32. #include "gdisplay.h"
  33. #include "gimpcontext.h"
  34. #include "gimage.h"
  35.  
  36. #include "libgimp/gimpparasite.h"
  37.  
  38. #include "libgimp/gimpintl.h"
  39.  
  40. #include "pixmaps/wilber2.xpm"
  41.  
  42.  
  43. static GList              *image_base_type_names = NULL;
  44. static GList              *fill_type_names = NULL;
  45. static GimpImageNewValues  last_values;
  46. static gboolean            current_cut_buffer = FALSE;
  47.  
  48. extern TileManager        *global_buf;
  49.  
  50. static void
  51. image_new_init (void)
  52. {
  53.   static gboolean image_new_inited = FALSE;
  54.  
  55.   GimpImageBaseTypeName *new_type;
  56.   GimpFillTypeName      *new_fill_type;
  57.  
  58.   if (image_new_inited)
  59.     return;
  60.   else
  61.     image_new_inited = TRUE;
  62.  
  63.   /* Available Image Base Types */
  64.   new_type = g_new (GimpImageBaseTypeName, 1);
  65.   new_type->type = RGB;
  66.   new_type->name = _("RGB");
  67.   image_base_type_names = g_list_append (image_base_type_names, new_type);
  68.  
  69.   new_type = g_new (GimpImageBaseTypeName, 1);
  70.   new_type->type = GRAY;
  71.   new_type->name = _("Grayscale");
  72.   image_base_type_names = g_list_append (image_base_type_names, new_type);
  73.   
  74.   /* Available Fill Types */
  75.   new_fill_type = g_new (GimpFillTypeName, 1);
  76.   new_fill_type->type = FOREGROUND_FILL;
  77.   new_fill_type->name = _("Foreground");
  78.   fill_type_names = g_list_append (fill_type_names, new_fill_type);
  79.  
  80.   new_fill_type = g_new (GimpFillTypeName, 1);
  81.   new_fill_type->type = BACKGROUND_FILL;
  82.   new_fill_type->name = _("Background");
  83.   fill_type_names = g_list_append (fill_type_names, new_fill_type);
  84.  
  85.   new_fill_type = g_new (GimpFillTypeName, 1);
  86.   new_fill_type->type = WHITE_FILL;
  87.   new_fill_type->name = _("White");
  88.   fill_type_names = g_list_append (fill_type_names, new_fill_type);
  89.  
  90.   new_fill_type = g_new (GimpFillTypeName, 1);
  91.   new_fill_type->type = TRANSPARENT_FILL;
  92.   new_fill_type->name = _("Transparent");
  93.   fill_type_names = g_list_append (fill_type_names, new_fill_type);
  94.  
  95.   /* Set the last values used to default values. */
  96.   last_values.width = default_width;
  97.   last_values.height = default_height;
  98.   last_values.unit = default_units;
  99.   last_values.xresolution = default_xresolution;
  100.   last_values.yresolution = default_yresolution;
  101.   last_values.res_unit = default_resolution_units;
  102.   last_values.type = default_type;
  103.   last_values.fill_type = BACKGROUND_FILL;
  104. }
  105.  
  106. GList *
  107. image_new_get_image_base_type_names (void)
  108. {
  109.   image_new_init ();
  110.  
  111.   return image_base_type_names;
  112. }
  113.  
  114. GList *
  115. image_new_get_fill_type_names (void)
  116. {
  117.   image_new_init ();
  118.  
  119.   return fill_type_names;
  120. }
  121.  
  122. void
  123. image_new_create_window (const GimpImageNewValues *create_values,
  124.                          const GimpImage          *image)
  125. {
  126.   GimpImageNewValues *values;
  127.  
  128.   image_new_init ();
  129.  
  130.   values = image_new_values_new (create_values);
  131.   
  132.   if (image)
  133.     {
  134.       values->width = gimp_image_get_width (image);
  135.       values->height = gimp_image_get_height (image);
  136.       values->unit = gimp_image_get_unit (image);
  137.       
  138.       gimp_image_get_resolution (image, 
  139.                  &values->xresolution, 
  140.                  &values->yresolution);
  141.  
  142.       values->type = gimp_image_base_type (image);
  143.  
  144.       if (values->type == INDEXED)
  145.         values->type = RGB; /* no indexed images */
  146.     }
  147.  
  148.   /*  If a cut buffer exists, default to using its size for the new image
  149.    *  also check to see if a new_image has been opened
  150.    */
  151.   if (global_buf && current_cut_buffer)
  152.     {
  153.       values->width = global_buf->width;
  154.       values->height = global_buf->height;
  155.     }
  156.  
  157.   ui_new_image_window_create (values);
  158.  
  159.   image_new_values_free (values);
  160. }
  161.  
  162. void
  163. image_new_set_default_values (const GimpImageNewValues *values)
  164. {
  165.   g_return_if_fail (values != NULL);
  166.  
  167.   image_new_init ();
  168.  
  169.   memcpy(&last_values, values, sizeof (GimpImageNewValues));
  170.  
  171.   current_cut_buffer = FALSE;
  172. }
  173.  
  174. GimpImageNewValues*
  175. image_new_values_new (const GimpImageNewValues *src_values)
  176. {
  177.   GimpImageNewValues *values;
  178.  
  179.   image_new_init ();
  180.  
  181.   values = g_new (GimpImageNewValues, 1);
  182.  
  183.   if (src_values)
  184.     memcpy(values, src_values, sizeof (GimpImageNewValues));
  185.   else
  186.     memcpy(values, &last_values, sizeof (GimpImageNewValues));
  187.  
  188.   return values;
  189. }
  190.  
  191. void
  192. image_new_values_free (GimpImageNewValues *values)
  193. {
  194.   g_return_if_fail (values != NULL);
  195.  
  196.   g_free (values);
  197. }
  198.  
  199. static gint
  200. image_new_rotate_the_shield_harmonics (GtkWidget    *widget,
  201.                        GdkEvent     *eevent,
  202.                        gpointer      data)
  203. {
  204.   GdkPixmap *pixmap = NULL;
  205.   GdkBitmap *mask   = NULL;
  206.   gint width  = 0;
  207.   gint height = 0;
  208.  
  209.   gtk_signal_disconnect_by_func 
  210.     (GTK_OBJECT (widget), 
  211.      GTK_SIGNAL_FUNC (image_new_rotate_the_shield_harmonics), data);
  212.  
  213.   pixmap =
  214.     gdk_pixmap_create_from_xpm_d (widget->window,
  215.                   &mask,
  216.                   NULL,
  217.                   wilber2_xpm);
  218.  
  219.   gdk_window_get_size (pixmap, &width, &height);
  220.  
  221.   if (widget->allocation.width  >= width &&
  222.       widget->allocation.height >= height)
  223.     {
  224.       gint x, y;
  225.  
  226.       x = (widget->allocation.width  - width) / 2;
  227.       y = (widget->allocation.height - height) / 2;
  228.  
  229.       gdk_gc_set_clip_mask (widget->style->black_gc, mask);
  230.       gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
  231.  
  232.       gdk_draw_pixmap (widget->window,
  233.                widget->style->black_gc,
  234.                pixmap, 0, 0,
  235.                x, y,
  236.                width, height);
  237.  
  238.       gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
  239.       gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
  240.     }
  241.  
  242.   gdk_pixmap_unref (pixmap);
  243.   gdk_bitmap_unref (mask);
  244.  
  245.   return FALSE;
  246. }
  247.  
  248. void 
  249. image_new_create_image (const GimpImageNewValues *values)
  250. {
  251.   GimpImage *image;
  252.   GDisplay *display;
  253.   Layer *layer;
  254.   GimpImageType type;
  255.   GimpParasite *comment_parasite;
  256.   gint width, height;
  257.  
  258.   g_return_if_fail (values != NULL);
  259.  
  260.   image_new_set_default_values (values);
  261.  
  262.   switch (values->fill_type)
  263.     {
  264.     case FOREGROUND_FILL:
  265.     case BACKGROUND_FILL:
  266.     case WHITE_FILL:
  267.       type = (values->type == RGB) ? RGB_GIMAGE : GRAY_GIMAGE;
  268.       break;
  269.     case TRANSPARENT_FILL:
  270.       type = (values->type == RGB) ? RGBA_GIMAGE : GRAYA_GIMAGE;
  271.       break;
  272.     default:
  273.       type = RGB_GIMAGE; 
  274.       break;
  275.     }
  276.  
  277.   image = gimage_new (values->width, values->height, values->type);
  278.   
  279.   gimp_image_set_resolution (image, values->xresolution, values->yresolution);
  280.   gimp_image_set_unit (image, values->unit);
  281.  
  282.   if (default_comment)
  283.     {
  284.       comment_parasite = gimp_parasite_new ("gimp-comment",
  285.                         GIMP_PARASITE_PERSISTENT,
  286.                         strlen (default_comment) + 1,
  287.                         (gpointer) default_comment);
  288.       gimp_image_parasite_attach (image, comment_parasite);
  289.       gimp_parasite_free (comment_parasite);
  290.     }
  291.   
  292.   /*  Make the background (or first) layer  */
  293.   width = gimp_image_get_width (image);
  294.   height = gimp_image_get_height (image);
  295.   layer = layer_new (image, width, height,
  296.                      type, _("Background"),
  297.              OPAQUE_OPACITY, NORMAL_MODE);
  298.  
  299.   if (layer)
  300.     {
  301.       /*  add the new layer to the gimage  */
  302.       gimp_image_undo_disable (image);
  303.       gimp_image_add_layer (image, layer, 0);
  304.       gimp_image_undo_enable (image);
  305.  
  306.       drawable_fill (GIMP_DRAWABLE (layer), values->fill_type);
  307.  
  308.       gimp_image_clean_all (image);
  309.  
  310.       display = gdisplay_new (image, 0x0101);
  311.  
  312.       gimp_context_set_display (gimp_context_get_user (), display);
  313.  
  314.       if (double_speed)
  315.     gtk_signal_connect_after
  316.       (GTK_OBJECT (display->canvas), "expose_event",
  317.        GTK_SIGNAL_FUNC (image_new_rotate_the_shield_harmonics),
  318.        NULL);
  319.     }
  320. }
  321.  
  322. gdouble
  323. image_new_calculate_size (GimpImageNewValues *values)
  324. {
  325.   gdouble width, height, size;
  326.  
  327.   width = (gdouble) values->width;
  328.   height = (gdouble) values->height;
  329.  
  330.   size = 
  331.     width * height *
  332.       ((values->type == RGB ? 3 : 1) +                   /* bytes per pixel */
  333.        (values->fill_type == TRANSPARENT_FILL ? 1 : 0)); /* alpha channel */
  334.  
  335.   return size;
  336. }
  337.  
  338. gchar *
  339. image_new_get_size_string (gdouble size)
  340. {
  341.   if (size < 4096)
  342.     return g_strdup_printf (_("%d Bytes"), (gint) size);
  343.   else if (size < 1024 * 10)
  344.     return g_strdup_printf (_("%.2f KB"), size / 1024);
  345.   else if (size < 1024 * 100)
  346.     return g_strdup_printf (_("%.1f KB"), size / 1024);
  347.   else if (size < 1024 * 1024)
  348.     return g_strdup_printf (_("%d KB"), (gint) size / 1024);
  349.   else if (size < 1024 * 1024 * 10)
  350.     return g_strdup_printf (_("%.2f MB"), size / 1024 / 1024);
  351.   else
  352.     return g_strdup_printf (_("%.1f MB"), size / 1024 / 1024);
  353. }
  354.  
  355. void
  356. image_new_reset_current_cut_buffer (void)
  357. {
  358.   /* This function just changes the status of current_cut_buffer
  359.      if there hass been a cut/copy since the last file new */
  360.   current_cut_buffer = TRUE;
  361. }
  362.  
  363.